package com.cskaoyan.config.shiro;

import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.LinkedHashMap;

/**
 * @Description:
 * @Author: WD created on 2021-09-18 11:04
 * @Version:
 */
@Configuration
public class ShiroConfig {

    @Value("${Info.expirationTime}")
    private long expirationTime;

    //创建 ShiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager manager) {
        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
        //设置安全器
        filterFactoryBean.setSecurityManager(manager);
        //LinkHashMap是有序的，shiro会根据添加的顺序进行拦截

        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        ///配置不会被拦截的连接  这里顺序判断
        //anon，所有的url都可以匿名访问
        //authc：所有url都必须认证通过才可以访问
        //user，配置记住我或者认证通过才能访问
        //logout，退出登录
        map.put("/admin/auth/login", "anon");
        map.put("/wx/auth/regCaptcha","anon");
        map.put("/wx/auth/register","anon");
        map.put("/wx/auth/reset","anon");
        map.put("/wx/auth/login", "anon");
        map.put("/pic/**", "anon");
        map.put("/wx/home/index", "anon");
        map.put("/wx/storage/upload", "anon");
        map.put("/unauthc", "anon");
        map.put("/**", "authc");

        filterFactoryBean.setFilterChainDefinitionMap(map);
        filterFactoryBean.setLoginUrl("/unauthc");
        return filterFactoryBean;
    }

    //创建 DefaultWebSecurityManager 2
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(
            AdminRealm adminRealm,
            WXUserRealm wxUserRealm,
            DefaultWebSessionManager sessionManager,
            CustomAuthenticator authenticator) {

        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        //整合realm
        manager.setRealm(adminRealm);
        manager.setSessionManager(sessionManager);
        manager.setAuthenticator(authenticator);
        return manager;
    }

    //创建 realm 对象 1
    @Bean
    public AdminRealm getUserRealm() {
        return new AdminRealm();
    }

    @Bean
    public WXUserRealm wxUserRealm() {
        return new WXUserRealm();
    }


    //SessionManager → 解决跨域过程中的session变化
    //需要自定义继承类重写setSessionId方法
    @Bean
    public DefaultWebSessionManager sessionManager() {
        MarketSessionManager marketSessionManager = new MarketSessionManager();
        //设置过期时间，配置文件中配置
        marketSessionManager.setGlobalSessionTimeout(expirationTime);
        return marketSessionManager;
    }

    //声明式鉴权需要的组件
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        //关联securityManager
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean
    public CustomAuthenticator authenticator(AdminRealm adminRealm,
                                             WXUserRealm wxUserRealm) {

        CustomAuthenticator authenticator = new CustomAuthenticator();

        ArrayList<Realm> realms = new ArrayList<>();
        realms.add(adminRealm);
        realms.add(wxUserRealm);
        authenticator.setRealms(realms);
        return authenticator;
    }


}
